package com.resys.server.controller.customer;

import com.resys.entity.dto.CustomerDto;
import com.resys.entity.dto.TokenCustomerDto;
import com.resys.entity.dto.TokenUserInfoDto;
import com.resys.entity.dto.UserInfoDto;
import com.resys.entity.po.Customer;
import com.resys.entity.po.User;
import com.resys.entity.vo.ResponseVO;
import com.resys.exception.BusinessException;
import com.resys.server.component.RedisComponent;
import com.resys.server.controller.ABaseController;
import com.resys.service.CustomerService;
import com.resys.service.UserService;
import com.wf.captcha.ArithmeticCaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Stream;

@RestController("CustomerAccountController")
@Slf4j
@RequestMapping("/customer/account")
@Api(tags = "客户模块-登录接口")
public class AccountController extends ABaseController {
    @Resource
    private UserService userService;
    @Resource
    private RedisComponent redisComponent;
    @Resource
    private CustomerService customerService;
    private final String UPLOAD_PATH = System.getProperty("user.dir") + "/static/avator/";
    @ApiOperation("获取验证码,返回base64编码加工的图片,且五分钟内有效")
    @GetMapping("/checkCode")
    public ResponseVO checkCode(){
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(100, 42);
        String code = captcha.text();
        String checkCodeKey = redisComponent.saveCheckCode(code);
        String checkCodeBase64 = captcha.toBase64();
        Map<String,String> result = new HashMap<>();
        result.put("checkCode",checkCodeBase64);
        result.put("checkCodeKey",checkCodeKey);
        return getSuccessResponseVO(result);
    }
    @PostMapping("/register")
    @ApiOperation("注册功能接口")
    public ResponseVO register(@NotEmpty String phone,
                               @NotEmpty @Size(max = 20)String userName,
                               @NotEmpty String registerPassword,
                               String realName,
                               String company,
                               @NotEmpty String checkCodeKey,
                               @NotEmpty String checkCode){
        try {
            if(!checkCode.equalsIgnoreCase(redisComponent.getCheckCode(checkCodeKey))){
                throw new BusinessException("图片验证码错误");
            }
            customerService.register(company,phone,userName,registerPassword,realName);
            return getSuccessResponseVO(null);
        }finally {
            redisComponent.deleteCheckCode(checkCodeKey);
        }

    }

    @ApiOperation("登录功能接口")
    @PostMapping("/login")
    public ResponseVO login(HttpServletResponse response,
                            HttpServletRequest request,
                            @NotEmpty String username,
                            @NotEmpty String password,
                            @NotEmpty String checkCodeKey,
                            @NotEmpty String checkCode) {
        try {
            if (!checkCode.equalsIgnoreCase(redisComponent.getCheckCode(checkCodeKey))) {
                throw new BusinessException("图片验证码错误");
            }
            Customer customer = customerService.getCustomerByClientName(username);
            String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
            if (customer == null) {
                throw new BusinessException("用户名不存在");
            } else if (customer.getAccountStatus() != 0) {
                throw new BusinessException("账号已被禁用");
            } else if (!md5Password.equals(customer.getPassword())) {
                throw new BusinessException("密码错误");
            }
            TokenCustomerDto tokenCustomerDto = new TokenCustomerDto();
            BeanUtils.copyProperties(customer, tokenCustomerDto);
            redisComponent.saveTokenInfo4Cilent(tokenCustomerDto);
            saveCilentToken2Cookie(response, tokenCustomerDto.getToken());
            customer.setLastloginAt(new Date());
            String ip = getIpAddr();
            customer.setLastloginIp(ip);
            customerService.updateCustomerByCustomerId(customer,customer.getCustomerId());
            return getSuccessResponseVO("登录成功");
        } finally {
            redisComponent.deleteCheckCode(checkCodeKey);

        }
    }
    @ApiOperation("自动登录功能接口")
    @GetMapping("/autoLogin")
    public ResponseVO autoLogin( HttpServletResponse response){

        TokenCustomerDto tokenCustomerDto = getTokenCustomer();
        if(tokenCustomerDto == null)
            return getServerErrorResponseVO("请先登录");

        if(tokenCustomerDto.getExpireAt() - System.currentTimeMillis()<60000*60){
            redisComponent.saveTokenInfo4Cilent(tokenCustomerDto);
            saveCilentToken2Cookie(response,tokenCustomerDto.getToken());
        }
        saveCilentToken2Cookie(response,tokenCustomerDto.getToken());
        Customer customer = customerService.getCustomerByCustomerId(tokenCustomerDto.getCustomerId());
        customer.setLastloginAt(new Date());
        String ip = getIpAddr();
        customer.setLastloginIp(ip);
        customerService.updateCustomerByCustomerId(customer,customer.getCustomerId());
        return getSuccessResponseVO(tokenCustomerDto);
    }
    @ApiOperation("退出登录")
    @GetMapping("/loginout")
    public ResponseVO loginout( HttpServletResponse response){
        cleanCookie(response,"customer");
        return getSuccessResponseVO(null);
    }
    @ApiOperation("获取当前登录用户信息")
    @GetMapping
    public ResponseVO account(){
        Customer customer = customerService.getCustomerByCustomerId(getTokenCustomer().getCustomerId());

        return getSuccessResponseVO(customer);
    }
    @ApiOperation("修改个人信息")
    @PostMapping("/update")
    public ResponseVO update(@RequestBody CustomerDto customerDto){

        TokenCustomerDto tokenCustomerDto =  getTokenCustomer();
        Customer customer = new Customer();
        customer = customerService.getCustomerByClientName(tokenCustomerDto.getClientName());
        if(customer!=null&&!customer.getCustomerId().equals(tokenCustomerDto.getCustomerId())){
            throw new BusinessException("用户名已存在");
        }

        BeanUtils.copyProperties(customerDto,customer);
        String password = customer.getPassword();
        if(password != null){
            customer.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        }else {
            customer.setPassword(getTokenCustomer().getPassword());
        }
        customerService.updateCustomerByCustomerId(customer,customer.getCustomerId());
        return getSuccessResponseVO("修改成功");
    }
    @ApiOperation("回显头像")
    @GetMapping("/avator")
    public ResponseEntity<byte[]> avator(){
        Customer customer = customerService.getCustomerByCustomerId(getTokenCustomer().getCustomerId());
        if(customer.getAvator()==null||customer==null){
            throw new BusinessException("无头像信息");
        }
        String filename =  customer.getAvator();
        Path path= Paths.get(UPLOAD_PATH);
        try {
            // 遍历目录查找文件
            Optional<Path> foundFile;
            try (Stream<Path> stream = Files.walk(path)) {
                foundFile = stream
                        .filter(Files::isRegularFile)
                        .filter(p -> p.getFileName().toString().equals(filename))
                        .findFirst();
            }

            // 读取文件内容
            Path filePath = foundFile.get();
            byte[] imageBytes = Files.readAllBytes(filePath);

            // 根据后缀确定MIME类型
            String fileExtension = filename.substring(filename.lastIndexOf('.') + 1);

            // 返回图片数据
            return ResponseEntity.ok()
                    .contentType(fileExtension.equalsIgnoreCase("png") ? MediaType.IMAGE_PNG : MediaType.IMAGE_JPEG)
                    .body(imageBytes);

        } catch (IOException e) {
            throw new BusinessException("头像读取失败", e);
        }
    }

    @ApiOperation("上传或修改头像")
    @PostMapping("/upload")
    public ResponseVO upload(@RequestParam("file") MultipartFile file){
        TokenCustomerDto tokenCustomerDto = getTokenCustomer();
        if (tokenCustomerDto == null) {
            throw new BusinessException("获取用户信息失败");
        }
        Customer customer = customerService.getCustomerByCustomerId(tokenCustomerDto.getCustomerId());
        if (customer == null) {
            throw new BusinessException("找不到对应的客户信息");
        }
        if(file.isEmpty()){
            throw new BusinessException("文件不能为空");
        }
        String originalFileName = file.getOriginalFilename();
        int lastDotIndex = originalFileName.lastIndexOf('.');
        if (lastDotIndex == -1) {
            throw new BusinessException("文件名不合法");
        } else if (lastDotIndex == originalFileName.length() - 1) {
            throw new BusinessException("文件名后缀不能为空");
        }
        String fileExtension = originalFileName.substring(lastDotIndex + 1);
        String newFileName = UUID.randomUUID().toString() + "." + fileExtension;

        Path uploadDir = Paths.get(UPLOAD_PATH);
        try {
            Files.createDirectories(uploadDir);
            Path filePath = uploadDir.resolve(newFileName);
            file.transferTo(filePath.toFile());
        } catch (IOException e) {
            throw new BusinessException("文件上传失败", e);
        }
        customer.setAvator(newFileName);
        customerService.updateCustomerByCustomerId(customer,customer.getCustomerId());
        return getSuccessResponseVO(null);
    }


}
